import secrets
from typing import Optional

from fastapi import HTTPException, Security, status
from fastapi.security import HTTPBasic, HTTPBasicCredentials

from authx.settings.config import settings


class BasicAuth:
    """
    - 初始化时可传入自定义 username/password；未传则使用默认值
    - 在 __call__ 上使用 HTTPBasic 作为依赖（Security/Depends 均可）
    - 返回用户名字符串（兼容官方示例风格）
    """

    def __init__(
        self,
        username: Optional[str] = None,
        password: Optional[str] = None,
        *,
        realm: str = "Restricted",
    ) -> None:
        self.expected_username = username or settings.HTTP_BASIC_USERNAME
        self.expected_password = password or settings.HTTP_BASIC_PASSWORD
        self.realm = realm

    def _unauthorized(self, detail: str) -> HTTPException:
        return HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail=detail,
            headers={"WWW-Authenticate": f'Basic realm="{self.realm}"'},
        )

    def __call__(
        self,
        credentials: Optional[HTTPBasicCredentials] = Security(
            HTTPBasic(auto_error=False)
        ),
    ) -> str:
        if credentials is None:
            raise self._unauthorized("Not authenticated")

        is_user_ok = secrets.compare_digest(
            credentials.username.encode("utf-8"),
            self.expected_username.encode("utf-8"),
        )
        is_pass_ok = secrets.compare_digest(
            credentials.password.encode("utf-8"),
            self.expected_password.encode("utf-8"),
        )
        if not (is_user_ok and is_pass_ok):
            raise self._unauthorized("Incorrect username or password")

        return credentials.username
